/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : freertos.c
  * Description        : Code for freertos applications
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "fatfs.h"
#include "sdio.h"
#include <stdio.h>
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */

/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
  .name = "defaultTask",
  .stack_size = 2048 * 4,
  .priority = (osPriority_t) osPriorityNormal,
};

/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
void SDCard_ShowInfo(void);
void SDCard_ShowStatus(void);
/* USER CODE END FunctionPrototypes */

void StartDefaultTask(void *argument);

void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

/**
  * @brief  FreeRTOS initialization
  * @param  None
  * @retval None
  */
void MX_FREERTOS_Init(void) {
  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* USER CODE BEGIN RTOS_MUTEX */
  /* add mutexes, ... */
  /* USER CODE END RTOS_MUTEX */

  /* USER CODE BEGIN RTOS_SEMAPHORES */
  /* add semaphores, ... */
  /* USER CODE END RTOS_SEMAPHORES */

  /* USER CODE BEGIN RTOS_TIMERS */
  /* start timers, add new ones, ... */
  /* USER CODE END RTOS_TIMERS */

  /* USER CODE BEGIN RTOS_QUEUES */
  /* add queues, ... */
  /* USER CODE END RTOS_QUEUES */

  /* Create the thread(s) */
  /* creation of defaultTask */
  defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

  /* USER CODE BEGIN RTOS_THREADS */
  /* add threads, ... */
  /* USER CODE END RTOS_THREADS */

  /* USER CODE BEGIN RTOS_EVENTS */
  /* add events, ... */
  /* USER CODE END RTOS_EVENTS */

}

/* USER CODE BEGIN Header_StartDefaultTask */
/**
  * @brief  Function implementing the defaultTask thread.
  * @param  argument: Not used
  * @retval None
  */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
  /*测试SD card FATFS */
  // printf("》SD card FATFS BSP_SD_Init %ld.\r\n", BSP_SD_Init());
  
  // printf("》SD card FATFS HAL_SD_GetCardState %ld.\r\n", HAL_SD_GetCardState(&hsd));

  printf("Compilation Date: %s %s\n", __DATE__, __TIME__);
  // mount SD card
  int retSD = f_mount(&SDFatFS, (TCHAR const *)SDPath, 1);
  if (retSD == FR_OK) {
      printf("》Filesystem mount ok, now you can read/write files.\r\n");
      // 创建或者打开文件 SD_Card_test.txt
      retSD = f_open(&SDFile, "SD_Card_test.txt", FA_OPEN_ALWAYS | FA_WRITE);
      if (retSD == FR_OK) {
          printf("》open/create SD_Card_test.txt OK, write data to it.\r\n");

          // Move to end of the file to append data
          retSD = f_lseek(&SDFile, f_size(&SDFile));
          if (retSD == FR_OK) {
              f_printf(&SDFile, "SD card FATFS test.\r\n");
              printf("》write data to file OK, write bytes: SD card FATFS test.\r\n");
          } else {
              printf("!! File Write error: (%d)\n", retSD);
          }
          /* close file */
          f_close(&SDFile);
      } else {
          printf("!! open/Create file SD_Card_test.txt Fail (%d).\r\n", retSD);
      }
  } else {
      printf("!! SDcard mount filesystem error。(%d)\r\n", retSD);
  }
  // 不带fatfs调试函数
  SDCard_ShowInfo();
  // SDCard_ShowStatus();
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END StartDefaultTask */
}

/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/*显示SD卡的信息*/
void SDCard_ShowInfo(void)
{
    // SD卡信息结构体变量
    HAL_SD_CardInfoTypeDef cardInfo;
    HAL_StatusTypeDef res = HAL_SD_GetCardInfo(&hsd, &cardInfo);
    if (res != HAL_OK) {
        printf("HAL_SD_GetCardInfo() error\r\n");
        return;
    }
    printf("\r\n*** HAL_SD_GetCardInfo() info ***\r\n");
    printf("Card Type= %ld\r\n", cardInfo.CardType);
    printf("Card Version= %ld\r\n", cardInfo.CardVersion);
    printf("Card Class= %ld\r\n", cardInfo.Class);
    printf("Relative Card Address= %ld\r\n", cardInfo.RelCardAdd);
    printf("Block Count= %ld\r\n", cardInfo.BlockNbr);
    printf("Block Size(Bytes)= %ld\r\n", cardInfo.BlockSize);
    printf("LogiBlockCount= %ld\r\n", cardInfo.LogBlockNbr);
    printf("LogiBlockSize(Bytes)= %ld\r\n", cardInfo.LogBlockSize);
    printf("SD Card Capacity(MB)= %ld\r\n", cardInfo.BlockNbr >> 1 >> 10);
}
// 获取SD卡当前状态
void SDCard_ShowStatus(void)
{
    // SD卡状态结构体变量
    HAL_SD_CardStatusTypeDef cardStatus;
    HAL_StatusTypeDef res = HAL_SD_GetCardStatus(&hsd, &cardStatus);
    if (res != HAL_OK) {
        printf("HAL_SD_GetCardStatus() error\r\n");
        return;
    }
    printf("\r\n*** HAL_SD_GetCardStatus() info ***\r\n");
    printf("DataBusWidth= %d\r\n", cardStatus.DataBusWidth);
    printf("CardType= %d\r\n", cardStatus.CardType);
    printf("SpeedClass= %d\r\n", cardStatus.SpeedClass);
    printf("AllocationUnitSize= %d\r\n", cardStatus.AllocationUnitSize);
    printf("EraseSize= %d\r\n", cardStatus.EraseSize);
    printf("EraseTimeout= %d\r\n", cardStatus.EraseTimeout);
}
/* USER CODE END Application */

